﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using PersonaLibrary.Data;
using PersonaLibrary.PrintReports;
using PersonaLibrary.PrintViewModel.Model;

namespace PersonaLibrary.ViewModel.PrintViewModel
{
	internal sealed class StickersTemplate : BasePrintTemplate, Model.IAvailableConflict, Model.ITemplateConfigurable
	{
		private readonly StickersProperty _property = new StickersProperty();
		private readonly ContactsConflictVM _conflicts = new ContactsConflictVM();

		private List<Grid> _controls;
		private readonly List<Border> _borders;

		private Dictionary<int, string> _employeeInPadej;

		private RelayCommand _config;
		private RelayCommand _conflict;

		private Dictionary<int, string> EmployeeInPadej
		{
			get
			{
				if (_employeeInPadej == null)
					_employeeInPadej = PadegVm.Sclonyat(Items);
				return _employeeInPadej;
			}
		}

		public StickersTemplate()
		{
			_property.Rows = new List<ReportItemParent>();

			_property.Rows.Add(new ReportItemParent
			            	{
								Header = "Организация"
			            	});

			_property.Rows[_property.Rows.Count - 1].ValueSelector = delegate(Employee arg)
			                                                         	{
			                                                         		return arg.DefaultOrganization;
			                                                         	};

			_property.Rows.Add(new ReportItemParent
			            	{
			            		Bold = FontWeights.Bold,
			            		ValueSelector = delegate(Employee arg)
			            		                	{
														if (EmployeeInPadej != null && EmployeeInPadej.Count == Items.Count)
															return EmployeeInPadej[arg.Id];

														return string.Format("{0} {1} {2}", arg.Surname, arg.Name, arg.Patronymic);
			            		                	},
								Header = "ФИО"
			            	});

			_property.Rows.Add(new ReportItemParent
			            	{
			            		ValueSelector = x => x.DefaultAddress,
								Header = "Адрес"
			            	});
			_borders = new List<Border>();

		}

		protected override IDocumentPaginatorSource CreateTable(System.Windows.Size pageSize, System.Windows.Thickness thickness)
		{
			if (_conflicts.AllConflictEmployee == null)
				_conflicts.AllConflictEmployee = new List<Employee>(Items.Where(item => item.IsConflict));

			Items = Items.OrderBy(x => x.ToString()).ToList();

			FixedDocument result = new FixedDocument();
			result.DocumentPaginator.PageSize = pageSize;

			int index = 0;
			double contentWidht = pageSize.Width - thickness.Left - thickness.Right;
			WrapPanel host = new WrapPanel { Margin = thickness, Width = contentWidht };
			PageContent page;

			Size columnSize = new Size(contentWidht/2.1, double.PositiveInfinity);
			Size contentSize = new Size(result.DocumentPaginator.PageSize.Width, double.PositiveInfinity);

			if(_controls == null)
				CreateControls();

			if(_borders != null)
			{
				foreach(Border border in _borders)
				{
					border.Child = null;
				}

				_borders.Clear();
			}


			while (index < _controls.Count)
			{
				Border border = new Border{ BorderThickness = new Thickness(0.3), BorderBrush = System.Windows.Media.Brushes.Black};

				Grid grid = _controls[index];

				grid.Width = contentWidht / 2.1;

				grid.Measure(columnSize);

				border.Child = grid;

				_borders.Add(border);

				host.Children.Add(border);

				host.Measure(contentSize);

				if (host.DesiredSize.Height > result.DocumentPaginator.PageSize.Height && host.Children.Count > 1)
				{
					border.Child = null;
					page = new PageContent();
					FixedPage fPage = new FixedPage();
					fPage.Children.Add(host);
					((IAddChild)page).AddChild(fPage);
					result.Pages.Add(page);
					host = new WrapPanel { Margin = thickness, Width = contentWidht };
				}
				else
					index++;
			}

			page = new PageContent();
			FixedPage fixPage = new FixedPage();
			fixPage.Children.Add(host);
			((IAddChild)page).AddChild(fixPage);
			result.Pages.Add(page);

			return result;
		}

		private void CreateControls()
		{
			_controls = new List<Grid>(Items.Count);

			foreach (Employee employee in Items)
			{
				Grid grid = new Grid();
				foreach (ReportItemParent parent in _property.Rows)
				{
					grid.RowDefinitions.Add(new RowDefinition());
					ReportItemText text = new ReportItemText(parent);
					FrameworkElement element = text.ToControl(employee);
					grid.Children.Add(element);
					Grid.SetRow(element, grid.RowDefinitions.Count - 1);
				}

				_controls.Add(grid);
			}
		}

		public RelayCommand ShowConfig
		{
			get
			{
				if (_config == null)
					_config = new RelayCommand(x => showConfig(), x => !_property.IsWindowOpened);
				return _config;
			}
		}

		private void showConfig()
		{
			_property.View.Show();
		}

		public RelayCommand ShowConflict
		{
			get
			{
				if (_conflict == null)
					_conflict = new RelayCommand(x => showConflict(), x => canShowConflict());
				return _conflict;
			}
		}

		private bool canShowConflict()
		{
			if (_conflicts.IsWindowOpened)
				return false;

			return true;
		}

		private void showConflict()
		{
			if (_conflicts.AllConflictEmployee == null)
				_conflicts.AllConflictEmployee = new List<Employee>(Items.Where(item => item.IsConflict));

			_conflicts.View.Show();
		}

		public override void UnLoad()
		{
			_conflicts.View.Close();
		}
	}
}
